const url = require('url');
const Layer = require('./layer');
const Route = require('./route');
const methods = require('methods');
function Router() {
    this.stack = [] // 路由表 
}
Router.prototype.use = function (path, ...handlers) {
    if (typeof path !== 'string') {
        handlers.unshift(path);
        path = '/'
    }
    // path = '路径' handlers所有用户提供的方法
    handlers.forEach(handler => {
        // 中间件是没有route属性， 区分是路由还是中间件就开layer.route
        this.stack.push(new Layer(path, handler))
    });
}
methods.forEach(method => {
    Router.prototype[method] = function (path, handlers) {
        let route = new Route();
        route[method](handlers)
        let layer = new Layer(path, route.dispatch.bind(route));

        // 每个层都配置了一个route属性，来存放用户的真实回调
        layer.route = route; // 只是标识而已
        this.stack.push(layer)
    }
})

Router.prototype.handle = function (req, res, out) {
    const { pathname } = url.parse(req.url, true);

    let idx = 0;
    const next = (err) => { // 路由中的next  err 包含了 里层的错误，也包含了外层的错误
        if (idx === this.stack.length) return out()
        let layer = this.stack[idx++];

        // 路径匹配到了

        // 无论路由还是中间件 都要匹配路径才能执行
        // 但是路由需要匹配方法
        if (layer.match(pathname)) {
            // layer.params
            req.params = layer.params;
            console.log(req.params)
            if (err) {
                // 找中间件 而且是错误处理中间件
                if (!layer.route) {
                    if (layer.handler.length === 4) {
                        layer.handle_error(err, req, res, next)
                    } else {
                        next(err);
                    }
                } else {
                    next(err);
                }
            } else {
                if (layer.route) { // 路由
                    if (layer.route.methods[req.method.toLowerCase()]) { // 让这一层去判断能否匹配，后续有复杂的匹配逻辑都可以交给layer的match方法来实现
                        layer.handle_request(req, res, next); // dispatch方法
                    } else {
                        next();
                    }
                } else {
                    if (layer.handler.length !== 4) {
                        layer.handle_request(req, res, next);
                    } else {
                        next();
                    }
                }
            }
        } else {
            next(err);
        }
    }
    // this.use((err, req, res, next) => {
    //     res.end(err + '')
    // });

    next();
}
module.exports = Router;


// Router 就是路由系统
// Route 存放注册路由时存放的真实回调
// Layer 外层的layer存放的是 路径 和 dispatch方法
//       里层的存放的是   没有路径 只有 用户方法 （标识了方法的类型）

// 外层的leayer 会关联Route